#include "stdafx.h"
#include "Util.h"

#define PRESET_VALUE	0xFFFF
#define POLYNOMIAL		0x8408

ERROR_NAME tbErrorName[]=
{
	{_T("Ok"),											ER_OK					},
	{_T("operation not implemented"),					ER_NOT_IMPLEMENTED		},
	{_T("no protocol"),									ER_NO_PROTOCOL			},
	{_T("error open"),									ER_OPEN					},
	{_T("error close"),									ER_CLOSE				},
	{_T("error write"),									ER_WRITE				},
	{_T("error read"),									ER_READ					},
	{_T("set speed error"),								ER_SET_SPEED			},
	{_T("set time out error"),							ER_SET_TIMEOUT			},
	{_T("error invalid data"),							ER_INVALID_DATA			},
	{_T("error size"),									ER_SIZE					},
	{_T("error no data available"),						ER_DATA					},
	{_T("error application"),							ER_WRONG_APP			},
	{_T("error command"),								ER_CMD					},
	{_T("error card state"),							ER_STATE				},
	{_T("no data received"),							ER_RCV_DATA				},
	{_T("invalid SAM found"),							ER_SAM_FOUND			},
	{_T("invalid SAM 63 found"),						ER_SAM63_FOUND			},
	{_T("invalid SAM 64 found. Delete data"),			ER_SAM64_FOUND_DATADEL	},
	{_T("invalid SAM 64 found. Data in memory"),		ER_SAM64_FOUND_DATAMEM	},
	{_T("invalid SAM 64 found. Memory full"),			ER_SAM64_FOUND_MEMFULL	},
	{_T("master-Token not supported"),					ER_MT_NOTSUPPORTED		},
	{_T("invalid checksum"),							ER_CRC					},
	{_T("no transport layer"),							ER_NO_TRANSPORT			},
	{_T("error executing command"),						ER_EXEC_CMD				},
	{_T("no tag detected"),								ER_NO_TAG				},
	{_T("other error"),									ER_OTHER_ERROR			},
	{_T("unknown error"),								ER_UNKNOWN				},
};

CUtil::CUtil()
{

}

CUtil::~CUtil()
{

}

UINT CUtil::CalcCRC16(BYTE* pData)
{
	UINT nCrc = PRESET_VALUE;
	if(pData != NULL)
	{
		UCHAR nSize = pData[0] - 2; // in a LEGIC command the
		for(int i = 0; i <= nSize; i++) // loop over all the bytes
		{
			nCrc = nCrc ^((pData[i])); 
			for(int j = 0; j < 8; ++j)
			{
				nCrc = (nCrc & 0x0001) ? ((nCrc >> 1)^POLYNOMIAL) : (nCrc >> 1);
			}
		}
	}
	return nCrc;
}

EERROR CUtil::GetError(BYTE bError)
{
	EERROR eRet = ER_UNKNOWN;
	switch(bError)
	{
		case 0x00: eRet = ER_OK;		break;
		case 0x01: eRet = ER_EXEC_CMD;	break;
		case 0x02: eRet = ER_SIZE;		break;
		case 0x03: eRet = ER_DATA;		break;
		case 0x04: eRet = ER_WRONG_APP;	break;
		case 0x05: eRet = ER_RCV_DATA;	break;

		case 0x80: eRet = ER_SAM_FOUND;				break;
		case 0x81: eRet = ER_SAM63_FOUND;			break;
		case 0x82: eRet = ER_SAM64_FOUND_DATADEL;	break;
		case 0x83: eRet = ER_SAM64_FOUND_DATAMEM;	break;
		case 0x84: eRet = ER_SAM64_FOUND_MEMFULL;	break;
		case 0x85: eRet = ER_MT_NOTSUPPORTED;		break;
	}
	return eRet;
}

TCHAR* CUtil::GetError(EERROR eError)
{
	for(UINT nCount = 0; nCount < sizeof(tbErrorName)/sizeof(ERROR_NAME); nCount++)
	{
		if(tbErrorName[nCount].eError == eError)
		{
			return tbErrorName[nCount].szError;
		}
	}
	return _T("Unknown error");
}

SdkString CUtil::ByteToString(BYTE* pData, UINT nSize)
{
	SdkString strRet = _T("");
	if((pData != NULL) && (nSize > 0))
	{
		TCHAR szData[MAX_PATH];
		for(UINT nCount = 0; nCount < nSize; nCount++)
		{
			_stprintf_s((TCHAR*)szData, MAX_PATH, _T("%02X"), pData[nCount]);
			strRet += szData;
		}
	}
	return strRet;
}

EERROR CUtil::SetDataStr(CHAR* szSrc, BYTE* pDest, DWORD& dwDestLen)
{
	EERROR eRet = ER_INVALID_POINTER;
	if((szSrc != NULL) && (pDest != NULL))
	{
		ZeroMemory(pDest, dwDestLen);
		DWORD dwTotalData = strlen(szSrc) <= (dwDestLen - 0x01) ? strlen(szSrc) : dwDestLen - 0x01;
		memcpy_s(pDest, dwDestLen, szSrc, dwTotalData);
		eRet = dwTotalData < (dwDestLen - 1) ? ER_OK : ER_MORE_DATA;
		dwDestLen = strlen(szSrc) + 0x01;
	}
	return eRet;
}

EERROR CUtil::SetDataByte(BYTE* pSrc, DWORD dwSrc, BYTE* pDest, DWORD& dwDestLen)
{
	EERROR eRet = ER_INVALID_POINTER;
	if((pSrc != NULL) && (pDest != NULL))
	{
		ZeroMemory(pDest, dwDestLen);
		DWORD dwTotalData = dwSrc <= dwDestLen ? dwSrc : dwDestLen;
		memcpy_s(pDest, dwDestLen, pSrc, dwTotalData);
		eRet = dwTotalData < dwDestLen ? ER_OK : ER_MORE_DATA;
		dwDestLen = dwSrc;
	}
	return eRet;
}
